package com.itrus.service;

import com.itrus.manager.WalletAdd1Manager;
import com.itrus.manager.WalletAdd2Manager;
import com.itrus.manager.WalletAdd3Manager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;


@Service
public class WalletService {

    @Resource
    private WalletAdd1Manager walletAdd1Manager;
    @Resource
    private WalletAdd2Manager walletAdd2Manager;
    @Resource
    private WalletAdd3Manager walletAdd3Manager;

    @Resource
    private TransactionTemplate transactionTemplate;

    public void simulateCode() throws SQLException {
        Connection connection = DriverManager.getConnection(""); //1

        connection.setAutoCommit(false); // 2
        // 3、业务逻辑代码
        connection.commit(); //  connection.rollback();

        connection.close(); //5
    }



    @Transactional
    public void use_method1(){
        walletAdd1Manager.addById1(false);
        walletAdd2Manager.addById2(true);
    }

    public void use_method2(){
        transactionTemplate.execute(status -> {
            walletAdd1Manager.addById1(false);
            walletAdd2Manager.addById2(true);
            return true;
        });
    }


    @Transactional(propagation = Propagation.REQUIRED)
    public void add1_1(){
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);
        walletAdd2Manager.addById2(true);
    }


    @Transactional(propagation = Propagation.REQUIRED)
    public void add1_2(){
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);
        walletAdd2Manager.addById2_new(true);
    }


    @Transactional(propagation = Propagation.REQUIRED)
    public void add2_1(){
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);

        walletAdd2Manager.addById2(false);

        int a = 1/0;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void add2_2(){
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);
        walletAdd2Manager.addById2_new(false);
        int a = 1/0;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void add2_3(){
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);
        walletAdd2Manager.addById2_nested(false);
        int a = 1/0;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void add3_1() throws Exception {
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);
        walletAdd2Manager.addById2(true);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void add3_2() {
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);
        walletAdd2Manager.addById2_nested(true);
    }




    @Transactional(propagation = Propagation.REQUIRED)
    public void add4_1() throws Exception {
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);
        try {
            walletAdd2Manager.addById2_new(true);
        } catch (Exception e){

        }
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void add4_2() throws Exception {
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);
        try {
            walletAdd2Manager.addById2_nested(true);
        } catch (Exception e){
//            throw new Exception("xxxxx");
        }
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void add4_3() throws Exception {
        walletAdd3Manager.addById3_no(false);
        walletAdd1Manager.addById1(false);
        try {
            add4_3_1();
        } catch (Exception e){
//            throw new Exception("xxxxx");
        }
    }

    @Transactional(propagation = Propagation.NESTED)
    public void add4_3_1(){
        walletAdd2Manager.addById2_no(true);
    }

    /**
     * Transaction rolled back because it has been marked as rollback-only
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void add5(){

        walletAdd1Manager.addById1(false);

        try {
            walletAdd2Manager.addById2(true);
        } catch (Exception e){
            throw new RuntimeException("xx");
        }
    }


}
